﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfNearestSide
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Canvas_MouseMove(object sender, MouseEventArgs e)
        {
            Point p = e.GetPosition(canvas);
            
            double nearestDistance = Double.MaxValue;
            Point nearestPoint = new Point();
            Point nearestPoint2;
            Point intersect = new Point();

            Point last = poly.Points[0];
            for (int i = 1; i <= poly.Points.Count; i++)
            {
                Point point;
                if (i != poly.Points.Count)
                {
                    point = poly.Points[i];
                }
                else
                {
                    point = poly.Points[0];
                }

                Point temp;
                double dist = 0;
                if ((dist = LineToPointDistance(last, point, p, out temp)) < nearestDistance)
                {
                    intersect = temp;
                    nearestDistance = dist;
                    nearestPoint = last;
                    nearestPoint2 = point;
                }

                last = point;
            }

            if (nearestDistance > 5000)
            {
                intersect.X = -5;
                intersect.Y = -5;
            }

            Canvas.SetLeft(ellipsePoint, intersect.X - 5);
            Canvas.SetTop(ellipsePoint, intersect.Y - 5);
           
            //int nearestPosition = 0;

            //int pos = 0;

            //// detect the nearest point 
            //foreach (Point point in poly.Points)
            //{
            //    double dist = CalculateDistance(p, point);
            //    if (dist < nearestDistance)
            //    {
            //        nearestPoint = point;
            //        nearestDistance = dist;
            //        nearestPosition = pos;
            //    }
            //    pos++;
            //}

            //Point prev = poly.Points[((nearestPosition - 1) + poly.Points.Count) % poly.Points.Count];
            //Point next = poly.Points[((nearestPosition + 1)) % poly.Points.Count];

            //if (CalculateDistance(p, prev) > CalculateDistance(p, next))
            //{
            //    // prev je dal nez next => chceme next
            //    nearestPoint2 = next;
            //}
            //else
            //{
            //    // next je dal nez prev => bereme prev
            //    nearestPoint2 = prev;
            //}

            //// nastav druhy nejblizsi bod jako zeleny
            //Canvas.SetLeft(ellipsePoint2, nearestPoint2.X - 5);
            //Canvas.SetTop(ellipsePoint2, nearestPoint2.Y - 5);

            //// nastav nejblizsi bod na cerveny
            //Canvas.SetLeft(ellipsePoint, nearestPoint.X - 5);
            //Canvas.SetTop(ellipsePoint, nearestPoint.Y - 5);
        }

        /// <summary>
        /// Lines to point distance.
        /// http://pastebin.com/CbMrH48e
        /// </summary>
        /// <param name="linePoint1">The line point1.</param>
        /// <param name="linePoint2">The line point2.</param>
        /// <param name="point">The point.</param>
        /// <returns></returns>
        private double LineToPointDistance(Point linePoint1, Point linePoint2, Point point, out Point intersect)
        {

            double u =
                    ((point.X - linePoint1.X) * (linePoint2.X - linePoint1.X) +
                    (point.Y - linePoint1.Y) * (linePoint2.Y - linePoint1.Y)) /
                    (linePoint2 - linePoint1).LengthSquared;

            intersect = new Point(
                linePoint1.X + u * (linePoint2.X - linePoint1.X),
                linePoint1.Y + u * (linePoint2.Y - linePoint1.Y)
            );

            if (Math.Min(linePoint1.X, linePoint2.X) <= intersect.X && intersect.X <= Math.Max(linePoint1.X, linePoint2.X)
                && Math.Min(linePoint1.Y, linePoint2.Y) <= intersect.Y && intersect.Y <= Math.Max(linePoint1.Y, linePoint2.Y))
            {
                Vector distance = Point.Subtract(intersect, point);

                // distance.X = Math.Abs(distance.X);
                // distance.Y = Math.Abs(distance.Y);

                return distance.LengthSquared;
            }
            else
            {
                return double.MaxValue;
            }
        }

        private void Test(Point p1, Point p2, Point p3)
        {
            // vektor primky
            Vector u = p1 - p2;
            // vektor normaly
            Vector n = new Vector(u.Y, (-1) * u.X);

            Point x = Vector.Add(n, p3);
        }

        private double CalculateDistance(Point p, Point point)
        {
            double w = p.X - point.X;
            double h = p.Y - point.Y;

            return Math.Sqrt(w * w + h * h);
        }

    }
}
